import {type Ref, unref} from "vue";
import {message} from "ant-design-vue";
import CrudApi from "../../core/CrudApi";
import type Named from "@/models/core/Named";
import {NamedImpl} from "@/models/core/Named";
import type {FormExpose} from "ant-design-vue/lib/form/Form";
import {BindThis} from "@/core/BindThis";
import type {ClassConstructor} from "class-transformer/types/interfaces";

declare type ModalEmitFn = (event: string, ...args: any[]) => void;

export declare type ModalExpose<V extends Named, T, CONTROLLER extends ModalController<V, T, ModalConfig<V, T>, CrudApi<V, T, any>>> = {
    emit: ModalEmitFn;
    controller: CONTROLLER;
}

export interface ModalConfig<V extends Named, T> {
    // 编辑窗口
    modal?: Ref<ModalExpose<V, T, any>>;
    // Modal中的Form窗口，可以有多个
  // forms?: Ref<FormExpose | Ref<FormExpose>>[];
    forms?: Ref<FormExpose>[],

    // 外部视图传入的对象
    row?: V;
    // 编辑的模型对象
    record?: T;
    // Modal窗口的开关控制
    visible?: boolean;
    // 提交的mask控制
    confirmLoading?: boolean;
}

export default class ModalController<V extends Named, T, CONFIG extends ModalConfig<V, T>, API extends CrudApi<V, T, any>> {
    // 模板构造参数
    protected clazzV?: ClassConstructor<V>;
    protected clazzT?: ClassConstructor<T>;
    protected clazzAPI?: ClassConstructor<API>;
    // config配置由VUE传入
    protected readonly config: CONFIG;
    // api接口在构造函数中自动初始化
    protected readonly api: API;

    constructor(config: CONFIG) {
        this.config = config;
        // 构造api
        this.api = new this.clazzAPI!;
        this.api.clazzV = this.clazzV;
        this.api.clazzT = this.clazzT;
        // 初始化config中的变量
        config.record ??= new this.clazzT!;
        config.visible = false;
        config.confirmLoading = false;
    }

    public setConfigForm(forms: Ref<FormExpose>[]) {
        this.config.forms = forms
    }

    @BindThis
    public edit(row: V) {
        this.config.row = row;
        this.api.findById(row.id).then(data => {
            this.config.record = data;
            this.config.visible = true;
        });
    }

    @BindThis
    public add(record: T) {
        this.config.row = undefined;
        this.config.record = record;
        this.config.visible = true;
    }

    @BindThis
    public title(): string {
        const record = this.config.record;
        if (record instanceof NamedImpl) {
            return (record!.id ? '编辑 ' : '新增 ') + (record!.name || '')
        }
        return `编辑 ${this.config.row?.name || ''}`;
    }

    @BindThis
    public submit() {
        const config = this.config;
      const promises = config.forms?.map(form => {
        // return form.value?.value?.validate() || form.value?.validate()
        return form.value?.validate()
        });
        promises && Promise.all(promises).then(() => {
            config.confirmLoading = true;
            this.api.submit(config.record!, this.config.row)
                .then(data => {
                    config.confirmLoading = false;
                    config.visible = false;
                    message.info('提交成功').then();
                    config.modal && unref(config.modal).emit('afterSubmit', data, this.config.row);
                })
                .catch(reason => {
                    config.confirmLoading = false;
                    message.error('提交失败').then();
                    // 修改错误提示
                    console.log(reason);
                })
        }).catch(reason => {
            config.modal && unref(config.modal).emit('validateFailed', reason);
            console.log(reason);
        })
    }
}